package lesson5.example1;


import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;

public class MyTransformer implements ClassFileTransformer {

	public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
	      ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
		 
	      ClassReader cr = new ClassReader(classfileBuffer);
	      ClassNode classNode = new ClassNode(Opcodes.ASM6);
	      cr.accept(classNode, ClassReader.SKIP_FRAMES);
	 
	      for (MethodNode methodNode : classNode.methods) {
	        if ("main".equals(methodNode.name)) {
	          InsnList instrumentation = new InsnList();
	          instrumentation.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
	          instrumentation.add(new LdcInsnNode("Hello, Instrumentation!"));
	          instrumentation.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false));
	 
	          methodNode.instructions.insert(instrumentation);
	        }
	      }
	 
	      ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
	      classNode.accept(cw);
	      return cw.toByteArray();
	    }

}
